import React, {
  createContext,
  useContext,
  useEffect,
  useReducer,
  ReactNode,
  useCallback,
} from "react";
import { message, notification } from "antd";
import { useAuth } from "./AuthContext";

// WebSocket消息类型
export interface WebSocketMessage {
  type: "message" | "notification" | "typing" | "online_status" | "heartbeat";
  data: any;
  timestamp: number;
  from?: number;
  to?: number;
}

// 连接状态
export type ConnectionStatus =
  | "connecting"
  | "connected"
  | "disconnected"
  | "error";

// WebSocket状态
interface WebSocketState {
  messageConnection: WebSocket | null;
  notificationConnection: WebSocket | null;
  messageStatus: ConnectionStatus;
  notificationStatus: ConnectionStatus;
  onlineUsers: number[];
  typingUsers: { [conversationId: string]: number[] };
  reconnectAttempts: number;
  lastHeartbeat: number;
}

// WebSocket操作
type WebSocketAction =
  | { type: "SET_MESSAGE_CONNECTION"; payload: WebSocket | null }
  | { type: "SET_NOTIFICATION_CONNECTION"; payload: WebSocket | null }
  | { type: "SET_MESSAGE_STATUS"; payload: ConnectionStatus }
  | { type: "SET_NOTIFICATION_STATUS"; payload: ConnectionStatus }
  | { type: "UPDATE_ONLINE_USERS"; payload: number[] }
  | {
      type: "ADD_TYPING_USER";
      payload: { conversationId: string; userId: number };
    }
  | {
      type: "REMOVE_TYPING_USER";
      payload: { conversationId: string; userId: number };
    }
  | { type: "INCREMENT_RECONNECT" }
  | { type: "RESET_RECONNECT" }
  | { type: "UPDATE_HEARTBEAT"; payload: number };

// WebSocket上下文接口
interface WebSocketContextType {
  state: WebSocketState;
  sendMessage: (message: any) => void;
  sendNotification: (notification: any) => void;
  sendTyping: (conversationId: string, isTyping: boolean) => void;
  isUserOnline: (userId: number) => boolean;
  isUserTyping: (conversationId: string, userId: number) => boolean;
  reconnect: () => void;
}

// 初始状态
const initialState: WebSocketState = {
  messageConnection: null,
  notificationConnection: null,
  messageStatus: "disconnected",
  notificationStatus: "disconnected",
  onlineUsers: [],
  typingUsers: {},
  reconnectAttempts: 0,
  lastHeartbeat: 0,
};

// Reducer
const webSocketReducer = (
  state: WebSocketState,
  action: WebSocketAction
): WebSocketState => {
  switch (action.type) {
    case "SET_MESSAGE_CONNECTION":
      return { ...state, messageConnection: action.payload };

    case "SET_NOTIFICATION_CONNECTION":
      return { ...state, notificationConnection: action.payload };

    case "SET_MESSAGE_STATUS":
      return { ...state, messageStatus: action.payload };

    case "SET_NOTIFICATION_STATUS":
      return { ...state, notificationStatus: action.payload };

    case "UPDATE_ONLINE_USERS":
      return { ...state, onlineUsers: action.payload };

    case "ADD_TYPING_USER":
      const { conversationId, userId } = action.payload;
      const currentTyping = state.typingUsers[conversationId] || [];
      if (!currentTyping.includes(userId)) {
        return {
          ...state,
          typingUsers: {
            ...state.typingUsers,
            [conversationId]: [...currentTyping, userId],
          },
        };
      }
      return state;

    case "REMOVE_TYPING_USER":
      const { conversationId: convId, userId: userIdToRemove } = action.payload;
      const typingUsers = state.typingUsers[convId] || [];
      return {
        ...state,
        typingUsers: {
          ...state.typingUsers,
          [convId]: typingUsers.filter((id) => id !== userIdToRemove),
        },
      };

    case "INCREMENT_RECONNECT":
      return { ...state, reconnectAttempts: state.reconnectAttempts + 1 };

    case "RESET_RECONNECT":
      return { ...state, reconnectAttempts: 0 };

    case "UPDATE_HEARTBEAT":
      return { ...state, lastHeartbeat: action.payload };

    default:
      return state;
  }
};

// 创建上下文
const WebSocketContext = createContext<WebSocketContextType | undefined>(
  undefined
);

// WebSocket提供者组件
export const WebSocketProvider: React.FC<{ children: ReactNode }> = ({
  children,
}) => {
  const [state, dispatch] = useReducer(webSocketReducer, initialState);
  const { state: authState } = useAuth();

  // 创建WebSocket连接
  const createConnection = useCallback(
    (type: "message" | "notification"): WebSocket | null => {
      if (!authState.user || !authState.isAuthenticated) return null;

      const wsUrl = `${process.env.REACT_APP_WS_URL || "ws://localhost:8080"}/ws/${type}?userId=${authState.user.id}`;
      const ws = new WebSocket(wsUrl);

      ws.onopen = () => {
        console.log(`${type} WebSocket连接成功`);
        if (type === "message") {
          dispatch({ type: "SET_MESSAGE_STATUS", payload: "connected" });
        } else {
          dispatch({ type: "SET_NOTIFICATION_STATUS", payload: "connected" });
        }
        dispatch({ type: "RESET_RECONNECT" });

        // 发送心跳
        const heartbeatMsg: WebSocketMessage = {
          type: "heartbeat",
          data: { userId: authState.user?.id },
          timestamp: Date.now(),
        };
        ws.send(JSON.stringify(heartbeatMsg));
      };

      ws.onmessage = (event) => {
        try {
          const message: WebSocketMessage = JSON.parse(event.data);
          handleWebSocketMessage(type, message);
        } catch (error) {
          console.error(`解析${type} WebSocket消息失败:`, error);
        }
      };

      ws.onclose = (event) => {
        console.log(`${type} WebSocket连接关闭:`, event.code, event.reason);
        if (type === "message") {
          dispatch({ type: "SET_MESSAGE_STATUS", payload: "disconnected" });
        } else {
          dispatch({
            type: "SET_NOTIFICATION_STATUS",
            payload: "disconnected",
          });
        }

        // 自动重连
        if (event.code !== 1000 && state.reconnectAttempts < 5) {
          setTimeout(
            () => {
              dispatch({ type: "INCREMENT_RECONNECT" });
              const newWs = createConnection(type);
              if (type === "message") {
                dispatch({ type: "SET_MESSAGE_CONNECTION", payload: newWs });
              } else {
                dispatch({
                  type: "SET_NOTIFICATION_CONNECTION",
                  payload: newWs,
                });
              }
            },
            Math.pow(2, state.reconnectAttempts) * 1000
          );
        }
      };

      ws.onerror = (error) => {
        console.error(`${type} WebSocket错误:`, error);
        if (type === "message") {
          dispatch({ type: "SET_MESSAGE_STATUS", payload: "error" });
        } else {
          dispatch({ type: "SET_NOTIFICATION_STATUS", payload: "error" });
        }
      };

      return ws;
    },
    [authState.user, authState.isAuthenticated, state.reconnectAttempts]
  );

  // 处理WebSocket消息
  const handleWebSocketMessage = (
    connectionType: "message" | "notification",
    message: WebSocketMessage
  ) => {
    switch (message.type) {
      case "message":
        // 新消息处理
        if (connectionType === "message") {
          // 触发消息事件
          window.dispatchEvent(
            new CustomEvent("newMessage", { detail: message.data })
          );

          // 显示消息通知
          if (message.from !== authState.user?.id) {
            notification.info({
              message: "新消息",
              description: `${message.data.fromUserInfo?.name || "未知用户"}: ${message.data.content}`,
              placement: "topRight",
              duration: 3,
            });
          }
        }
        break;

      case "notification":
        // 新通知处理
        if (connectionType === "notification") {
          window.dispatchEvent(
            new CustomEvent("newNotification", { detail: message.data })
          );

          // 显示系统通知
          const notificationData = message.data;
          notification.open({
            message: notificationData.title,
            description: notificationData.content,
            placement: "topRight",
            duration: notificationData.priority === 4 ? 0 : 5, // 紧急通知不自动关闭
            type: notificationData.priority >= 3 ? "warning" : "info",
          });
        }
        break;

      case "typing":
        // 打字状态
        if (message.data.isTyping) {
          dispatch({
            type: "ADD_TYPING_USER",
            payload: {
              conversationId: message.data.conversationId,
              userId: message.from!,
            },
          });

          // 3秒后自动移除打字状态
          setTimeout(() => {
            dispatch({
              type: "REMOVE_TYPING_USER",
              payload: {
                conversationId: message.data.conversationId,
                userId: message.from!,
              },
            });
          }, 3000);
        } else {
          dispatch({
            type: "REMOVE_TYPING_USER",
            payload: {
              conversationId: message.data.conversationId,
              userId: message.from!,
            },
          });
        }
        break;

      case "online_status":
        // 在线状态更新
        dispatch({
          type: "UPDATE_ONLINE_USERS",
          payload: message.data.onlineUsers || [],
        });
        break;

      case "heartbeat":
        // 心跳响应
        dispatch({ type: "UPDATE_HEARTBEAT", payload: Date.now() });
        break;

      default:
        console.log("未知的WebSocket消息类型:", message.type);
    }
  };

  // 初始化WebSocket连接
  useEffect(() => {
    if (authState.isAuthenticated && authState.user) {
      const messageWs = createConnection("message");
      const notificationWs = createConnection("notification");

      dispatch({ type: "SET_MESSAGE_CONNECTION", payload: messageWs });
      dispatch({
        type: "SET_NOTIFICATION_CONNECTION",
        payload: notificationWs,
      });

      return () => {
        if (messageWs) messageWs.close(1000, "用户主动断开");
        if (notificationWs) notificationWs.close(1000, "用户主动断开");
      };
    }
  }, [authState.isAuthenticated, authState.user, createConnection]);

  // 心跳检测
  useEffect(() => {
    if (
      state.messageStatus === "connected" ||
      state.notificationStatus === "connected"
    ) {
      const heartbeatInterval = setInterval(() => {
        const now = Date.now();

        // 发送心跳到消息连接
        if (state.messageConnection?.readyState === WebSocket.OPEN) {
          const heartbeatMsg: WebSocketMessage = {
            type: "heartbeat",
            data: { userId: authState.user?.id },
            timestamp: now,
          };
          state.messageConnection.send(JSON.stringify(heartbeatMsg));
        }

        // 检查心跳超时
        if (state.lastHeartbeat > 0 && now - state.lastHeartbeat > 30000) {
          console.warn("心跳超时，准备重连");
          reconnect();
        }
      }, 15000); // 每15秒发送心跳

      return () => clearInterval(heartbeatInterval);
    }
  }, [
    state.messageStatus,
    state.notificationStatus,
    state.lastHeartbeat,
    authState.user,
  ]);

  // 发送消息
  const sendMessage = (messageData: any) => {
    if (state.messageConnection?.readyState === WebSocket.OPEN) {
      const message: WebSocketMessage = {
        type: "message",
        data: messageData,
        timestamp: Date.now(),
        from: authState.user?.id,
      };
      state.messageConnection.send(JSON.stringify(message));
    } else {
      message.error("消息连接未建立");
    }
  };

  // 发送通知
  const sendNotification = (notificationData: any) => {
    if (state.notificationConnection?.readyState === WebSocket.OPEN) {
      const message: WebSocketMessage = {
        type: "notification",
        data: notificationData,
        timestamp: Date.now(),
        from: authState.user?.id,
      };
      state.notificationConnection.send(JSON.stringify(message));
    } else {
      message.error("通知连接未建立");
    }
  };

  // 发送打字状态
  const sendTyping = (conversationId: string, isTyping: boolean) => {
    if (state.messageConnection?.readyState === WebSocket.OPEN) {
      const message: WebSocketMessage = {
        type: "typing",
        data: { conversationId, isTyping },
        timestamp: Date.now(),
        from: authState.user?.id,
      };
      state.messageConnection.send(JSON.stringify(message));
    }
  };

  // 检查用户是否在线
  const isUserOnline = (userId: number): boolean => {
    return state.onlineUsers.includes(userId);
  };

  // 检查用户是否正在打字
  const isUserTyping = (conversationId: string, userId: number): boolean => {
    const typingUsers = state.typingUsers[conversationId] || [];
    return typingUsers.includes(userId);
  };

  // 重连
  const reconnect = () => {
    if (state.messageConnection) state.messageConnection.close();
    if (state.notificationConnection) state.notificationConnection.close();

    setTimeout(() => {
      const messageWs = createConnection("message");
      const notificationWs = createConnection("notification");

      dispatch({ type: "SET_MESSAGE_CONNECTION", payload: messageWs });
      dispatch({
        type: "SET_NOTIFICATION_CONNECTION",
        payload: notificationWs,
      });
    }, 1000);
  };

  const contextValue: WebSocketContextType = {
    state,
    sendMessage,
    sendNotification,
    sendTyping,
    isUserOnline,
    isUserTyping,
    reconnect,
  };

  return (
    <WebSocketContext.Provider value={contextValue}>
      {children}
    </WebSocketContext.Provider>
  );
};

// 使用WebSocket上下文的Hook
export const useWebSocket = (): WebSocketContextType => {
  const context = useContext(WebSocketContext);
  if (context === undefined) {
    throw new Error("useWebSocket must be used within a WebSocketProvider");
  }
  return context;
};

// 连接状态指示器组件
export const ConnectionStatus: React.FC = () => {
  const { state } = useWebSocket();

  const getStatusColor = (status: ConnectionStatus) => {
    switch (status) {
      case "connected":
        return "#52c41a";
      case "connecting":
        return "#1890ff";
      case "disconnected":
        return "#d9d9d9";
      case "error":
        return "#ff4d4f";
    }
  };

  const getStatusText = (status: ConnectionStatus) => {
    switch (status) {
      case "connected":
        return "已连接";
      case "connecting":
        return "连接中";
      case "disconnected":
        return "已断开";
      case "error":
        return "连接错误";
    }
  };

  return (
    <div
      style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12 }}
    >
      <div style={{ display: "flex", alignItems: "center", gap: 4 }}>
        <div
          style={{
            width: 8,
            height: 8,
            borderRadius: "50%",
            backgroundColor: getStatusColor(state.messageStatus),
          }}
        />
        <span>消息: {getStatusText(state.messageStatus)}</span>
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 4 }}>
        <div
          style={{
            width: 8,
            height: 8,
            borderRadius: "50%",
            backgroundColor: getStatusColor(state.notificationStatus),
          }}
        />
        <span>通知: {getStatusText(state.notificationStatus)}</span>
      </div>
    </div>
  );
};
